package com.hulizuofang.wol.chat.server;

import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.nicocube.appengine.util.dao.Dao;
import org.nicocube.appengine.util.dao.DaoQuery;
import org.nicocube.appengine.util.dao.DaoRequest;
import org.nicocube.appengine.util.dao.DaoResultContainer;
import org.nicocube.appengine.util.dao.NoResultFoundException;
import org.nicocube.appengine.util.dao.PersistenceAccessor;

import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.hulizuofang.wol.chat.client.data.ChatUser;

@Singleton
public class ChatUserRepository {
	private final static Logger logger = Logger.getLogger(ChatUserRepository.class.getName());
	
	private final Dao dao;

	@Inject
	public ChatUserRepository(Dao dao) {
		this.dao = dao;
	}
	
	public ChatUser login(final String login) {
		final DaoResultContainer<ChatUser> result = new DaoResultContainer<ChatUser>();
		dao.eval(new DaoRequest() {
			@Override
			public void playOn(PersistenceAccessor pa) {
				DaoQuery<ChatUserJDO> query = pa.newQuery(ChatUserJDO.class);
				query.addCriteria("login", String.class, login);
				try {
					ChatUserJDO chatUser = query.execute();
					chatUser.setActive(true);
					result.set(pa.makePersistent(chatUser).asChatUser());
				} catch (NoResultFoundException e) {
					result.set(pa.makePersistent(new ChatUserJDO(login)).asChatUser());
				}
			}
			@Override
			public void onFailure(Throwable caught) {
				String msg = String.format("While fetching ChatUser for %s", login);
				logger.log(Level.SEVERE, msg, caught);
				throw new IllegalStateException(msg);
			}
		});
		return result.get();
	}

	public Set<ChatUser> getOnlineUsers(final String login) {
		final Set<ChatUser> result = new HashSet<ChatUser>();
		dao.eval(new DaoRequest() {
			@Override
			public void playOn(PersistenceAccessor pa) {
				DaoQuery<ChatUserJDO> query = pa.newQuery(ChatUserJDO.class);
				//query.addStatement(new NotStatement(new Param<String>("login", String.class, Op.eq, login)));
				//query.addCriteria("login", String.class, login);
				query.addCriteria("active", boolean.class, true);
				for (ChatUserJDO c : query.executeList()) {
					if (! login.equals(c.getLogin())) {
						result.add(c.asChatUser());
					}
				}
			}
			@Override
			public void onFailure(Throwable caught) {
				String msg = String.format("While fetching Online Users for %s", login);
				logger.log(Level.SEVERE, msg, caught);
				throw new IllegalStateException(msg);
			}
		});
		return result;
	}


}
